package io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;

/**
 * @program: rocsun
 * @description:
 * @author: yx.guo
 * @create: 2025-03-13 19:00
 **/
public class Nio {

    public static final String FILE_NAME = "/Users/yx.guo/Documents/study/test.txt";

    public void nio() throws IOException {

        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.bind(new InetSocketAddress(8080));
        ssc.configureBlocking(false);
        ssc.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 阻塞等待就绪时间，底层可能是select或者epoll
            selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                iterator.remove();
                if (selectionKey.isAcceptable()) {
                    SocketChannel socketChannel = ssc.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                }
                else if (selectionKey.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int read = socketChannel.read(buffer);

                    if (read < 0) {
                        socketChannel.close();
                    } else {
                        // 将缓冲区状态转换成可读（默认可写）
                        buffer.flip();

                        byte[] array = buffer.array();
                        String s = Arrays.toString(array);
                        System.out.println(s);
                    }
                } else if (selectionKey.isConnectable()) {

                }
            }


        }


    }

    public void fileTest() {
        try (FileChannel read = FileChannel.open(Paths.get(FILE_NAME), StandardOpenOption.READ);
             FileChannel write = FileChannel.open(Paths.get(FILE_NAME), StandardOpenOption.WRITE, StandardOpenOption.CREATE)
        ) {
//            byte[] bytes = new byte[1024];
//            ByteBuffer wrap = ByteBuffer.wrap(bytes);
//            read.read(wrap);

            // 复制文件
            read.transferTo(0, read.size(), write);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void fileAIOTest() throws IOException {
        AsynchronousFileChannel open = AsynchronousFileChannel.open(Paths.get(FILE_NAME), StandardOpenOption.READ);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        open.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                attachment.flip();
                byte[] data = new byte[attachment.remaining()];
                attachment.get(data);
                System.out.println(new String(data));
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        System.out.println("线程执行完毕后执行其他任务！");
    }

    public void testAIONet() throws IOException {

        AsynchronousServerSocketChannel assc = AsynchronousServerSocketChannel.open();
        assc.bind(new InetSocketAddress(8080));




    }

    public void testCharSet() {
        Charset charset = Charset.forName("UTF-8");
        CharBuffer encode = charset.decode(ByteBuffer.wrap("你好世界！".getBytes()));
        ByteBuffer encode1 = charset.encode(encode);
        System.out.println(new String(encode1.array()));


    }


    public static void main(String[] args) {
        try {
            fileAIOTest();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
